Skip to content

sugarloaf: shape UI text in per-font runs - #1973

Open
legibet wants to merge 1 commit into
raphamorim:mainfrom
legibet:fix/ui-text-font-runs
Open

legibet wants to merge 1 commit into
raphamorim:mainfrom
legibet:fix/ui-text-font-runs

Conversation

@legibet

@legibet legibet commented Oct 10, 2026

Copy link
Copy Markdown

Fixes #1971

UI text (tab titles, command palette, search, tooltips) resolved one font from the first character and shaped the whole string with it. On macOS, CoreText cascades the characters that font lacks to another font, but the resulting glyph IDs were rasterized against the first character's font and drew unrelated glyphs. The swash path drew .notdef for the same characters.

The bug does not need an uncovered first character. With the default font, vim 文件.txt is also affected.

This PR resolves the font per grapheme cluster and shapes each span of same-font clusters as its own run, using FontLibrary::resolve_font_for_char, so titles follow the same fallbacks as the terminal. The public Text API is unchanged, so no call sites change. The shape cache now stores the runs for a whole string, keyed before font resolution.

Notes:

  • DrawOpts::font_id still forces a single run in that font. No caller sets it today.
  • The doc comment on shape_text said substituted glyphs come out as .notdef. It now says they draw unrelated glyphs.

Testing:

  • New tests in text.rs: mixed-font strings get the same font and glyph per character as when shaped alone, mixed text splits into per-font runs with additive widths, and a combining mark stays in its base's run.
  • cargo test -p sugarloaf, clippy and fmt pass on macOS.
  • Checked by hand on macOS with ◑ 中文标题 and vim 文件.txt as tab titles. Not tested on Linux or Windows.

UI text resolved one font from the first character and shaped the whole
string with it. On macOS, CoreText substituted cascade fonts for
characters that font lacks, but every glyph ID was still rasterized
against the first character's font, drawing unrelated glyphs. Tab titles
such as `◑ 中文标题` or `vim 文件.txt` were affected. The swash path drew
.notdef for the same characters.

Resolve the font per grapheme cluster and shape each span of
same-font clusters as its own run, as the terminal grid does.

Fixes raphamorim#1971
narma added a commit to narma/rio that referenced this pull request Oct 11, 2026
Adapt whole-string shaping cache and CJK checks from PR raphamorim#1973;
combine pixel snapping from PR raphamorim#1680 with stable title baselines.
Use tab-font configuration names with backwards-compatible aliases.

Co-authored-by: legibet <273362620+legibet@users.noreply.github.com>
Co-authored-by: cantona <35635+cantona@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS: CJK characters in tab titles render as unrelated glyphs

1 participant